package cn.fresh.xuanyuan.module.trade.service.strategy;

import cn.fresh.xuanyuan.framework.common.util.wx.WxUtil;
import cn.fresh.xuanyuan.module.pay.api.order.PayOrderApi;
import cn.fresh.xuanyuan.module.pay.api.order.dto.PayOrderDto;
import cn.fresh.xuanyuan.module.system.api.social.SocialClientApi;
import cn.fresh.xuanyuan.module.system.api.social.SocialUserApi;
import cn.fresh.xuanyuan.module.system.api.social.dto.SocialUserRespDTO;
import cn.fresh.xuanyuan.module.system.enums.social.SocialTypeEnum;
import cn.fresh.xuanyuan.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.fresh.xuanyuan.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.fresh.xuanyuan.module.trade.dal.mysql.order.TradeOrderItemMapper;
import cn.fresh.xuanyuan.module.trade.dto.UploadOrderStatusDto;
import cn.fresh.xuanyuan.module.trade.enums.order.TradeOrderStatusEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Component("wxSyncOrderStatusStrategy")
@Slf4j
public class WxSyncOrderStatusStrategy implements SyncOrderStatusStrategy {

    @Resource
    private PayOrderApi payOrderApi;

    @Resource
    private SocialUserApi socialUserApi;

    @Resource
    private SocialClientApi socialClientApi;

    @Resource
    private TradeOrderItemMapper tradeOrderItemMapper;

    @Override
    public void push(TradeOrderDO order, List<TradeOrderItemDO> itemList, PayOrderDto payOrderDto) {
        try {
            SocialUserRespDTO user = socialUserApi.getSocialUserByUserId(1, order.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType()).getCheckedData();
            String appId = payOrderApi.getPayAppId(String.valueOf(order.getId())).getCheckedData();
            if(user != null && StringUtils.isNotBlank(user.getOpenid())) {
                boolean allDelivered = isAllDelivered(order.getId());
                String accessToken = socialClientApi.getAccessToken(appId).getCheckedData();
                Map<String, Object> params = buildWxParams(user.getOpenid(), itemList.get(0), payOrderDto.getChannelOrderNo(),allDelivered);
                String result = WxUtil.uploadShippingInfo(accessToken, params);
                log.info("upload wx order result: {}", result);
                if(StringUtils.isNotBlank(result)) {
                    JSONObject json = JSON.parseObject(result);
                    if("0".equalsIgnoreCase(json.getString("errcode"))) {
                        for(TradeOrderItemDO item : itemList) {
                            tradeOrderItemMapper.updateUploadWx(item.getId());
                        }
                    }
                }
            }
        }
        catch (Exception e) {
            log.error("uploadShippingInfo exception:", e);
        }
    }

    private boolean isAllDelivered(Long orderId) {
        List<TradeOrderItemDO> list = tradeOrderItemMapper.selectListByOrderId(orderId);
        boolean allDelivered;
        int count = 0;
        for (TradeOrderItemDO itemDO: list) {
            if(Objects.equals(itemDO.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus())
                    || Objects.equals(itemDO.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus())
                    || Objects.equals(itemDO.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus()) ) {
                count += 1;
            }
        }
        allDelivered = count == list.size();
        return allDelivered;
    }

    private Map<String, Object> buildWxParams(String openId,TradeOrderItemDO orderItem, String channelPayNo, boolean allDelivered) {
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> orderKey = new HashMap<>();
        orderKey.put("order_number_type", 2);
        orderKey.put("transaction_id", channelPayNo);
        params.put("order_key", orderKey);
        params.put("logistics_type", 1);
        params.put("delivery_mode",2);
        params.put("is_all_delivered", allDelivered);
        List<Map<String, Object>> shippingList = new ArrayList<>();
        Map<String, Object> shipping = new HashMap<>();
        shipping.put("tracking_no", orderItem.getLogisticsNo());
        shipping.put("express_company", orderItem.getExpressName());
        shipping.put("item_desc", orderItem.getSpuName());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        String formatDate = simpleDateFormat.format(new Date());
        params.put("upload_time", formatDate);
        shippingList.add(shipping);
        params.put("shipping_list", shippingList);
        Map<String, Object> payer = new HashMap<>();
        payer.put("openid", openId);
        params.put("payer", payer);
        return params;
    }
}
